
package grapho;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class Graph {
    private LerArquivo lerArquivo;
    
    public Graph()
    {
        lerArquivo = new LerArquivo();
    }
    
    public Graph(String rootPath)
    {
        lerArquivo = new LerArquivo(rootPath);
    }

    public ArrayList<Aluno> getAmigos(int rm)
    {
        ArrayList<Aluno> alunos = new ArrayList<Aluno>();
        
        if(lerArquivo.getData().containsKey(rm))
        {
            Aluno aluno = lerArquivo.getData().get(rm);
            
            for(int alunoRm : aluno.getAlunoRms())
            {
                if(lerArquivo.getData().containsKey(alunoRm))
                {
                    alunos.add(lerArquivo.getData().get(alunoRm));
                }
                else
                {
                    alunos.add(new Aluno(alunoRm));
                }
            }
        }
        
        return alunos;
    }
    
    public ArrayList<Aluno> getTodosAlunos()
    {
        ArrayList<Aluno> alunos = new ArrayList<Aluno>();
        
        for(Map.Entry<Integer, Aluno> entry : lerArquivo.getData().entrySet())
        {
            Aluno valor = entry.getValue();
            
            alunos.add(valor);
        }
        
        return alunos;
    }
    
    public ArrayList<Aluno> getTodoAluno()
    {
        ArrayList<Aluno> alunos = new ArrayList<Aluno>();
        
        for(Map.Entry<Integer, Aluno> entry : lerArquivo.getData().entrySet())
        {
            Aluno valor = entry.getValue();
            
            if(!alunos.contains(valor))
            {
                alunos.add(valor);
            }
            
            for(int alunoRm : valor.getAlunoRms())
            {
                Aluno aluno = lerArquivo.getData().get(alunoRm);
                
                if(aluno == null)
                {
                    aluno = new Aluno(alunoRm);
                }
                
                if(!alunos.contains(aluno))
                {
                    alunos.add(aluno);
                }
            }
        }
        
        return alunos;
    }
    
    public ArrayList<ArrayList<Aluno>> getEstudanteConectado(int rm)
    {
        return getEstudanteConectado(rm, -1);
    }
    
    public ArrayList<ArrayList<Aluno>> getEstudanteConectado(int rm, int max)
    {   
        ArrayList<Aluno> alunosHistory = new ArrayList<Aluno>();
        HashMap<Integer, ArrayList<Aluno>> hashMapEstudante = new HashMap<Integer, ArrayList<Aluno>>();
        
        getEstudanteConectado(rm, -1, alunosHistory, hashMapEstudante, max, 0);
        
        ArrayList<ArrayList<Aluno>> estudanteConectado = new ArrayList<ArrayList<Aluno>>();
        
        Iterator iterator = hashMapEstudante.entrySet().iterator();
        
        while(iterator.hasNext())
        {
            Map.Entry pairs = (Map.Entry) iterator.next();
            
            ArrayList<Aluno> alunos = (ArrayList<Aluno>) pairs.getValue();
            
            estudanteConectado.add(alunos);
            
            iterator.remove();
        }
        
        return estudanteConectado;
    }
    
    public ArrayList<Aluno> getEstudanteDesconectado(int rm)
    {
        ArrayList<Aluno> estudantes = getTodoAluno();
        ArrayList<ArrayList<Aluno>> estudanteConectado = getEstudanteConectado(rm);
        
        ArrayList<Aluno> unestudanteConectado = new ArrayList<Aluno>();
        
        for(Aluno aluno : estudantes)
        {
            boolean estudanteConectadoContains = false;
            
            for(ArrayList<Aluno> alunos : estudanteConectado)
            {
                if((estudanteConectadoContains = alunos.contains(aluno)))
                {
                    break;
                }
            }
            
            if(!estudanteConectadoContains && aluno.getRm() != rm)
            {
                unestudanteConectado.add(aluno);
            }
        }
        
        return unestudanteConectado;
    }
    
    private void getEstudanteConectado(int baseRm, int currentRm, ArrayList<Aluno> alunosHistory, HashMap<Integer, ArrayList<Aluno>> hashMapEstudante, int maxDeep, int currentDeep)
    {
        if(currentDeep++ < maxDeep || maxDeep == -1)
        {
            int rm = currentRm == -1? baseRm : currentRm;

            ArrayList<Aluno> alunos = getAmigos(rm);

            for(Aluno aluno : alunos)
            {
                if(aluno.getRm() != baseRm)
                {
                    if(!alunosHistory.contains(aluno))
                    {
                        alunosHistory.add(aluno);
                        
                        if(!hashMapEstudante.containsKey(currentDeep))
                        {
                            hashMapEstudante.put(currentDeep, new ArrayList<Aluno>());
                        }
                        
                        hashMapEstudante.get(currentDeep).add(aluno);

                        getEstudanteConectado(baseRm, aluno.getRm(), alunosHistory, hashMapEstudante, maxDeep, currentDeep);
                    }
                }
            }
        }
    }
}
